<?xml version='1.0' encoding='iso-8859-1'?>
<!doctype html public '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html xmlns='http://www.w3c.org/1999/xhtml' lang='en-us'>
	<head>
		<title>
			CMEncrypt.c
			</title>
		<meta http-equiv='content-type' content='text/html;iso-8859-1'/>
		<meta name='generator' content='motley-tools 1.9.4 13:40:33 Feb 18 2015'/>
		<meta name='author' content='cmaier@cmassoc.net'/>
		<meta name='robots' content='noindex,nofollow'/>
		<link href='toolkit.css' rel='stylesheet' type='text/css'/>
		</head>
	<body>
		<div class='headerlink'>
			[<a href='clr32bitmap.c.html' title=' clr32bitmap.c '>PREV</a>]
			[<a href='toolkit.html' title=' Index '>HOME</a>]
			[<a href='codelist.c.html' title=' codelist.c '>NEXT</a>]
			</div>
<pre>
/*====================================================================*
 *
 *   Copyright (c) 2013 Qualcomm Atheros, Inc.
 *
 *   All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or 
 *   without modification, are permitted (subject to the limitations 
 *   in the disclaimer below) provided that the following conditions 
 *   are met:
 *
 *   * Redistributions of source code must retain the above copyright 
 *     notice, this list of conditions and the following disclaimer.
 *
 *   * Redistributions in binary form must reproduce the above 
 *     copyright notice, this list of conditions and the following 
 *     disclaimer in the documentation and/or other materials 
 *     provided with the distribution.
 *
 *   * Neither the name of Qualcomm Atheros nor the names of 
 *     its contributors may be used to endorse or promote products 
 *     derived from this software without specific prior written 
 *     permission.
 *
 *   NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE 
 *   GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE 
 *   COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND ANY EXPRESS OR 
 *   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
 *   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
 *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 *   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 *   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 *   OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 *
 *--------------------------------------------------------------------*/

/*====================================================================*
 *
 *   CMEncrypt - Send Encrypted Payload;
 *
 *   this program sends and receives raw ethernet frames and so needs
 *   root privileges; if you install it using &quot;chmod 555&quot; and &quot;chown
 *   root:root&quot; then you must login as root to run it; otherwise, you
 *   can install it using &quot;chmod 4555&quot; and &quot;chown root:root&quot; so that
 *   anyone can run it; the program will refuse to run until you get
 *   things right;
 *
 *
 *   Contributor(s):
 *      Charles Maier &lt;cmaier@qca.qualcomm.com&gt;
 *
 *--------------------------------------------------------------------*/

/*====================================================================*&quot;
 *   system header files;
 *--------------------------------------------------------------------*/

#include &lt;unistd.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdint.h&gt;
#include &lt;time.h&gt;

/*====================================================================*
 *   custom header files;
 *--------------------------------------------------------------------*/

#include &quot;../tools/getoptv.h&quot;
#include &quot;../tools/putoptv.h&quot;
#include &quot;../tools/memory.h&quot;
#include &quot;../tools/number.h&quot;
#include &quot;../tools/symbol.h&quot;
#include &quot;../tools/types.h&quot;
#include &quot;../tools/flags.h&quot;
#include &quot;../tools/files.h&quot;
#include &quot;../tools/error.h&quot;
#include &quot;../key/SHA256.h&quot;
#include &quot;../plc/plc.h&quot;

/*====================================================================*
 *   custom source files;
 *--------------------------------------------------------------------*/

#ifndef MAKEFILE
#include &quot;../tools/getoptv.c&quot;
#include &quot;../tools/putoptv.c&quot;
#include &quot;../tools/version.c&quot;
#include &quot;../tools/uintspec.c&quot;
#include &quot;../tools/hexencode.c&quot;
#include &quot;../tools/hexdecode.c&quot;
#include &quot;../tools/hexdump.c&quot;
#include &quot;../tools/todigit.c&quot;
#include &quot;../tools/error.c&quot;
#include &quot;../tools/synonym.c&quot;
#endif

#ifndef MAKEFILE
#include &quot;../plc/Confirm.c&quot;
#include &quot;../plc/Failure.c&quot;
#include &quot;../plc/Request.c&quot;
#include &quot;../plc/Devices.c&quot;
#endif

#ifndef MAKEFILE
#include &quot;../ether/channel.c&quot;
#include &quot;../ether/openchannel.c&quot;
#include &quot;../ether/closechannel.c&quot;
#include &quot;../ether/readpacket.c&quot;
#include &quot;../ether/sendpacket.c&quot;
#endif

#ifndef MAKEFILE
#include &quot;../key/SHA256Reset.c&quot;
#include &quot;../key/SHA256Write.c&quot;
#include &quot;../key/SHA256Block.c&quot;
#include &quot;../key/SHA256Fetch.c&quot;
#endif

#ifndef MAKEFILE
#include &quot;../mme/EthernetHeader.c&quot;
#include &quot;../mme/HomePlugHeader.c&quot;
#include &quot;../mme/MMECode.c&quot;
#endif

/*====================================================================*
 *   program constants;
 *--------------------------------------------------------------------*/

#define CMENCRYPT_PEKS 0x0F
#define CMENCRYPT_AVLN 0x00
#define CMENCRYPT_PID 0x04

/*====================================================================*
 *
 *   int main (int argc, char const * argv[]);
 *
 *
 *--------------------------------------------------------------------*/

int main (int argc, char const * argv [])

{
	extern struct channel channel;
	static char const * optv [] =
	{
		&quot;A:f:i:K:P:qv&quot;,
		&quot;device [device] [...]&quot;,
		&quot;Send an encrypted payload using CM_ENCRYPTED_PAYLOAD&quot;,
		&quot;A n\tAVLN Status [&quot; LITERAL (CMENCRYPT_AVLN) &quot;]&quot;,
		&quot;K n\tPayload Encryption Key Select (PEKS) [&quot; LITERAL (CMENCRYPT_PEKS) &quot;]&quot;,
		&quot;P n\tProtocol Identifier (PID) [&quot; LITERAL (CMENCRYPT_PID) &quot;]&quot;,

#if defined (WINPCAP) || defined (LIBPCAP)

		&quot;i n\thost interface is (n) [&quot; LITERAL (CHANNEL_ETHNUMBER) &quot;]&quot;,

#else

		&quot;i s\thost interface is (s) [&quot; LITERAL (CHANNEL_ETHDEVICE) &quot;]&quot;,

#endif

		&quot;f f\tpayload file&quot;,
		&quot;q\tquiet mode&quot;,
		&quot;v\tverbose mode&quot;,
		(char const *) (0)
	};

#ifndef __GNUC__
#pragma pack(push,1)
#endif

	struct __packed cm_encrypted_payload
	{
		uint8_t PEKS;
		uint8_t AVLN;
		uint8_t PID;
		uint16_t PRN;
		uint8_t PMN;
		uint8_t UUID [16];
		uint16_t LEN;
	}
	template =
	{
		CMENCRYPT_PEKS,
		CMENCRYPT_AVLN,
		CMENCRYPT_PID,
		0x0000,
		0x00,
		{
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00
		},
		0x0000
	};

#ifndef __GNUC__
#pragma pack (pop)
#endif

	struct _file_ file =
	{
		-1,
		(char const *) (0)
	};
	struct sha256 sha256;
	uint8_t digest [SHA256_DIGEST_LENGTH];
	time_t timer = time ((time_t *)(0));
	uint8_t packet [ETHER_MAX_LEN];
	uint8_t * buffer;
	signed extent;
	signed c;
	if (getenv (PLCDEVICE))
	{

#if defined (WINPCAP) || defined (LIBPCAP)

		channel.ifindex = atoi (getenv (PLCDEVICE));

#else

		channel.ifname = strdup (getenv (PLCDEVICE));

#endif

	}
	optind = 1;
	while ((c = getoptv (argc, argv, optv)) != -1)
	{
		switch (c)
		{
		case 'f':
			if ((file.file = open (file.name = optarg, O_BINARY|O_RDONLY)) == -1)
			{
				error (1, errno, &quot;%s&quot;, file.name);
			}
			break;
		case 'P':
			template.PID = (byte)(uintspec (optarg, 0x00, 0x0F));
			break;
		case 'A':
			template.AVLN = (byte)(uintspec (optarg, 0x00, 0x08));
			break;
		case 'K':
			template.PEKS = (byte)(uintspec (optarg, 0x00, 0xFF));
			break;
		case 'i':

#if defined (WINPCAP) || defined (LIBPCAP)

			channel.ifindex = atoi (optarg);

#else

			channel.ifname = optarg;

#endif

			break;
		case 'q':
			_setbits (channel.flags, CHANNEL_SILENCE);
			break;
		case 'v':
			_setbits (channel.flags, CHANNEL_VERBOSE);
			break;
		default:
			break;
		}
	}
	argc -= optind;
	argv += optind;

/*
 *	load entire file into memory;
 */

	if (file.file == -1)
	{
		error (1, ECANCELED, &quot;No payload file given: Use -f &lt;file&gt;&quot;);
	}
	if ((extent = lseek (file.file, 0, SEEK_END)) == -1)
	{
		error (1, errno, FILE_CANTSIZE, file.name);
	}
	if (!(buffer = malloc (extent)))
	{
		error (1, errno, FILE_CANTLOAD, file.name);
	}
	if (lseek (file.file, 0, SEEK_SET))
	{
		error (1, errno, FILE_CANTHOME, file.name);
	}
	if (read (file.file, buffer, extent) != extent)
	{
		error (1, errno, FILE_CANTREAD, file.name);
	}
	close (file.file);
	SHA256Reset (&amp;sha256);
	SHA256Write (&amp;sha256, buffer, extent);
	SHA256Fetch (&amp;sha256, digest);
	if (!argc)
	{
		error (1, ECANCELED, &quot;No destination given&quot;);
	}
	openchannel (&amp;channel);
	while ((argc) &amp;&amp; (* argv))
	{
		signed offset = 0;
		signed remain = extent;

#if 0

		signed length = sizeof (struct packet_ms) - sizeof (template);

#else

		signed length = 502 - sizeof (template);

#endif

		if (!hexencode (channel.peer, sizeof (channel.peer), synonym (* argv, devices, SIZEOF (devices))))
		{
			error (1, errno, PLC_BAD_MAC, * argv);
		}
		template.PRN = (uint16_t)(timer);
		template.PMN = 0;
		memcpy (template.UUID, digest, sizeof (template.UUID));
		while (remain)
		{
			uint8_t * memory = packet;
			if (length &gt; remain)
			{
				length = remain;
			}
			template.PMN++;
			template.LEN = HTOLE16 (length);
			memset (memory, 0, sizeof (struct message));
			memory += EthernetHeader ((struct ethernet_hdr *)(memory), channel.peer, channel.host, channel.type);
			memory += HomePlugHeader ((struct homeplug_hdr *)(memory), 0, (CM_ENCRYPTED_PAYLOAD | MMTYPE_IND));
			memcpy (memory, &amp;template, sizeof (template));
			memory += sizeof (template);
			memcpy (memory, buffer + offset, length);
			memory += length;
			extent = (signed)(memory - packet);
			if (extent &lt; (ETHER_MIN_LEN - ETHER_CRC_LEN))
			{
				extent = (ETHER_MIN_LEN - ETHER_CRC_LEN);
			}
			if (sendpacket (&amp;channel, packet, extent) &lt; extent)
			{
				error (1, errno, CHANNEL_CANTSEND);
			}
			offset += length;
			remain -= length;
		}
		argc--;
		argv++;
	}
	closechannel (&amp;channel);
	free (buffer);
	exit (0);
}


</pre>
		<div class='footerlink'>
			[<a href='clr32bitmap.c.html' title=' clr32bitmap.c '>PREV</a>]
			[<a href='toolkit.html' title=' Index '>HOME</a>]
			[<a href='codelist.c.html' title=' codelist.c '>NEXT</a>]
			</div>
		</body>
	</html>
